#include "PreCompiled.h"
#include "MenuManager.h"
#include "MainWindow.h"
#include "Command.h"
#include "Application.h"
MenuItem::MenuItem()
{

}
MenuItem::MenuItem(MenuItem* item)
{
	if(item)
   item->appendItem(this);
}
MenuItem::~MenuItem()
{
  clear();
}

void MenuItem::setComamnd(const std::string& name)
{
   _name = name;
}
std::string MenuItem::command()const
{
   return _name;
}

int MenuItem::count()const
{
	return _items.count();
}
bool MenuItem::hasItem()const
{
	return (_items.count()?1:0);
}
void MenuItem::appendItem(MenuItem* item)
{
    _items.push_back(item);
}
MenuItem* MenuItem::findItem(const std::string& name)
{
	if(_name == name)
		return this;
	for (QList<MenuItem*>::Iterator it = _items.begin(); it != _items.end(); it++)
	{
		if((*it)->_name == name)
			return *it;
	}
	return 0;
}
MenuItem* MenuItem::copy()const
{
	MenuItem* root = new MenuItem;
	root->setComamnd(command());
	QList<MenuItem*> items = getItems();
	for(QList<MenuItem*>::ConstIterator it = items.begin(); it != items.end(); it++)
	{
		root->appendItem((*it)->copy());
	}
	return root;
}
bool MenuItem::insertItem(MenuItem*before,MenuItem*item)
{
   int pos = _items.indexOf(before);
   if(pos != -1)
   {
	   _items.insert(pos,item);
	   return true;
   }
   return false;
}
void MenuItem::removeItem(MenuItem* item)
{
    int pos = _items.indexOf(item);
	if(pos != -1)
	{
		_items.removeAt(pos);
	}
}
void MenuItem::clear()
{
	for(QList<MenuItem*>::ConstIterator it = _items.begin(); it != _items.end(); it++)
	{
		delete *it;
	}
	_items.clear();
}
MenuItem& MenuItem::operator <<(MenuItem* item)
{
	appendItem(item);
   return *this;
}
MenuItem& MenuItem::operator <<(const std::string& name)
{
	MenuItem* item = new MenuItem(this);
	item->setComamnd(name);
   return *this;
}
QList<MenuItem*> MenuItem::getItems()const
{
   return _items;
}



// ---------------------------------- [4/17/2013 Administrator]

MenuManager* MenuManager::_instance = NULL;

MenuManager::MenuManager(void)
{
}

MenuManager::~MenuManager(void)
{
}

MenuManager* MenuManager::Instance()
{
    if(_instance == NULL)
		_instance = new MenuManager;
	return _instance;
}
void MenuManager::destruct()
{
   delete _instance;
   _instance = NULL;
}

void MenuManager::setup(MenuItem* menuItem)
{
    if(!menuItem)
		return;

	QList<MenuItem*> items = menuItem->getItems();
    QMenuBar* menubar = getMainWindow()->menuBar();
     QList<QAction*>actions = menubar->actions();
	for(QList<MenuItem*>::ConstIterator it = items.begin(); it != items.end();++it)
	{
		QAction* action = findAction(actions,QString::fromAscii((*it)->command().c_str()));
		 if(!action)
		 {
             if((*it)->command() == "Separator")
			 {
				 action = menubar->addSeparator();
				 action->setObjectName(QLatin1String("Separator"));
			 }else
			 {
				 std::string menuName = (*it)->command();
				 QMenu* menu = menubar->addMenu(QApplication::translate("Workbench",menuName.c_str(),0,QApplication::UnicodeUTF8));

				 action = menu->menuAction();

				 menu->setObjectName(QString::fromAscii((*it)->command().c_str()));
				 action->setObjectName(QString::fromAscii(menuName.c_str()));

				 action->setData(QString::fromAscii(menuName.c_str()));
			 }
		 }else
		 {
             menubar->removeAction(action);
			 menubar->addAction(action);
			 action->setVisible(true);
			 int index = actions.indexOf(action);
			 actions.removeAt(index);
		 }

		 if(!action->isSeparator())
		 {
			 setup(*it,action->menu());
		 }
	}

//  	for (QList<QAction*>::Iterator it = actions.begin(); it != actions.end();it++)
//  	{
//  		(*it)->setVisible(false);
//  	}

}
void MenuManager::setupContextMenu(MenuItem* item,QMenu &menu)const
{
    setup(item,&menu);
}

void MenuManager::setup(MenuItem* item,QMenu* menu)const
{
	CommandManager& mgr = Application::Instance()->commandMananger();
    QList<MenuItem*>items = item->getItems();
	QList<QAction*>actions = menu->actions();
	for(QList<MenuItem*>::Iterator it = items.begin();it != items.end(); ++it)
	{
		QList<QAction*> used_actions = findActions(actions,QString::fromAscii((*it)->command().c_str()));
		if(used_actions.isEmpty())
		{
			if((*it)->command() == "Separator")
			{
                QAction* action = menu->addSeparator();
				action->setObjectName(QLatin1String("Separator"));
				action->setData(QLatin1String("Separator"));
				used_actions.append(action);
			}else
			{
                if((*it)->hasItem())
				{
					std::string menuName = (*it)->command();
					QMenu* subMenu = menu->addMenu(QApplication::translate("Workbench",menuName.c_str(),0,QApplication::UnicodeUTF8));
					QAction* action = subMenu->menuAction();
					action->setObjectName(QString::fromAscii((*it)->command().c_str()));
					subMenu->setObjectName(QString::fromAscii((*it)->command().c_str()));
					used_actions.append(action);
				}else
				{
					int count = menu->actions().count();
					if(mgr.addTo((*it)->command().c_str(),menu))
					{
						QList<QAction*>acts = menu->actions();
						for(int i = 0; i<count; i++)
						{
							QAction* a = acts[i];
							a->setData(QString::fromAscii((*it)->command().c_str()));
							used_actions.append(a);
						}
					}
				}
			}

		}
		else
		{
			for (QList<QAction*>::Iterator it = used_actions.begin(); it != used_actions.end(); it++)
             {
				 menu->removeAction(*it);
				 menu->addAction(*it);
				 int pos = actions.indexOf(*it);
				 actions.removeAt(pos);
             }
		}

		if((*it)->hasItem())
		{
			setup(*it,used_actions.front()->menu());
		}
	}

	for (QList<QAction*>::Iterator it = actions.begin(); it != actions.end(); it++)
	{
		menu->removeAction(*it);
	}

}
QAction* MenuManager::findAction(const QList<QAction*>& acts, const QString& item)const
{
	for(QList<QAction*>::ConstIterator it = acts.begin(); it != acts.end(); it++)
	{
        if((*it)->data().toString() == item)
			return *it;
	}
	return NULL;

}
QList<QAction*>MenuManager::findActions(const QList<QAction*>& acts,const QString&item)const
{
	QList<QAction*> used;
	bool first_match = false;
	for(QList<QAction*>::ConstIterator it = acts.begin(); it != acts.end(); it++)
	{
		if((*it)->data().toString() == item)
		{
			used.append(*it);
		   first_match = true;
		   if(item == QLatin1String("Separator"))
			   break;;
		}
		else if(first_match)
			break;
	}
    return used;
}
